﻿using System.Web.UI;
using System.Web.UI.HtmlControls;

using netaddICTs.Umb.ProtectedMedia.Business.Configuration;
using netaddICTs.Umb.ProtectedMedia.Business.Encryption;
using netaddICTs.Umb.ProtectedMedia.Business.IO;

using umbraco;
using umbraco.cms.businesslogic;
using umbraco.editorControls;
using umbraco.interfaces;

using DefaultData = umbraco.cms.businesslogic.datatype.DefaultData;

namespace netaddICTs.Umb.ProtectedMedia.Datatypes.ProtectedUploadField {

    public sealed class DataEditor : HtmlInputFile, IDataEditor {

        private readonly DefaultData _defaultData;

        public DataEditor(IData data) {
            _defaultData = (DefaultData)data;
        }

        #region IDataEditor Members

        public Control Editor {
            get { return this; }
        }

        public void Save() {
            var config = Business.Configuration.ProtectedMedia.Instance;
            var fileStorageImplementation = FileStorageFactory.GetFileStorageImplementation();

            var content = Content.GetContentFromVersion(_defaultData.Version);

            if (string.Compare(helper.Request(string.Concat(ClientID, Constants.ClearFieldHtmlId)), Constants.PropertyTrueValue, true) == 0) {
                var mediaNodeId = int.Parse(helper.Request(string.Concat(ClientID, Constants.HiddenFieldHtmlId)));
                var deleteOk = fileStorageImplementation.Delete(mediaNodeId);

                if (deleteOk) {
                    try {
                        content.getProperty(config.Aliases.FileAlias.UmbracoAlias).Value = string.Empty;
                        content.getProperty(config.Aliases.InternalFileAlias.UmbracoAlias).Value = string.Empty;
                        var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.InternalFileAlias.UmbracoAlias);
                        if (ctrl != null) ctrl.RefreshLabel(string.Empty);
                    }
                        // ReSharper disable EmptyGeneralCatchClause
                    catch { }
                    // ReSharper restore EmptyGeneralCatchClause

                    try {
                        content.getProperty(config.Aliases.InternalDownloadLinkAlias.UmbracoAlias).Value = string.Empty;
                        var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.InternalDownloadLinkAlias.UmbracoAlias);
                        if (ctrl != null) ctrl.RefreshLabel(string.Empty);
                    }
                        // ReSharper disable EmptyGeneralCatchClause
                    catch { }
                    // ReSharper restore EmptyGeneralCatchClause

                    try {
                        content.getProperty(config.Aliases.FileExtensionAlias.UmbracoAlias).Value = string.Empty;
                        var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.FileExtensionAlias.UmbracoAlias);
                        if (ctrl != null) ctrl.RefreshLabel(string.Empty);
                    }
                        // ReSharper disable EmptyGeneralCatchClause
                    catch { }
                    // ReSharper restore EmptyGeneralCatchClause

                    try {
                        content.getProperty(config.Aliases.FileSizeAlias.UmbracoAlias).Value = string.Empty;
                        var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.FileSizeAlias.UmbracoAlias);
                        if (ctrl != null) ctrl.RefreshLabel(string.Empty);
                    }
                        // ReSharper disable EmptyGeneralCatchClause
                    catch { }
                    // ReSharper restore EmptyGeneralCatchClause
                }
            }

            if (PostedFile == null) return;
            if (PostedFile.FileName == "") return;

            var createOk = fileStorageImplementation.Create(_defaultData.NodeId, PostedFile);

            if (!createOk) {
            } else {
                try {
                    content.getProperty(config.Aliases.FileAlias.UmbracoAlias).Value =
                        string.Format("{0}?{1}={2}&{3}={4}", Constants.DownloadURL, Constants.IdQsKey, _defaultData.NodeId, Constants.HashCodeQsKey, Hash(_defaultData.NodeId));
                    content.getProperty(config.Aliases.InternalFileAlias.UmbracoAlias).Value =
                        string.Format("{0}", System.IO.Path.GetFileName(PostedFile.FileName));
                    var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.InternalFileAlias.UmbracoAlias);
                    if (ctrl != null)
                        ctrl.RefreshLabel(content.getProperty(config.Aliases.InternalFileAlias.UmbracoAlias).Value.ToString());
                }
                    // ReSharper disable EmptyGeneralCatchClause
                catch
                    // ReSharper restore EmptyGeneralCatchClause
                {
                }

                try {
                    content.getProperty(config.Aliases.InternalDownloadLinkAlias.UmbracoAlias).Value =
                        string.Format("<a href=\"{0}?{1}={2}&{3}={4}\"target=\"_blank\">{5}</a>", Constants.DownloadURL, Constants.IdQsKey, _defaultData.NodeId, Constants.HashCodeQsKey,
                            InternalDownloadHash(_defaultData.NodeId), System.IO.Path.GetFileName(PostedFile.FileName));

                    var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.InternalDownloadLinkAlias.UmbracoAlias);
                    if (ctrl != null)
                        ctrl.RefreshLabel(content.getProperty(config.Aliases.InternalDownloadLinkAlias.UmbracoAlias).Value.ToString());
                }
                    // ReSharper disable EmptyGeneralCatchClause
                catch
                    // ReSharper restore EmptyGeneralCatchClause
                {
                }

                try {
                    content.getProperty(config.Aliases.FileExtensionAlias.UmbracoAlias).Value = System.IO.Path.GetExtension(PostedFile.FileName).Substring(1);
                    var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.FileExtensionAlias.UmbracoAlias);
                    if (ctrl != null)
                        ctrl.RefreshLabel(content.getProperty(config.Aliases.FileExtensionAlias.UmbracoAlias).Value.ToString());
                }
                    // ReSharper disable EmptyGeneralCatchClause
                catch
                    // ReSharper restore EmptyGeneralCatchClause
                {
                }

                try {
                    content.getProperty(config.Aliases.FileSizeAlias.UmbracoAlias).Value =
                        fileStorageImplementation.CalculateBytes(_defaultData.NodeId, PostedFile);
                    var ctrl = FindControlRecursive<noEdit>(Page, config.Aliases.FileSizeAlias.UmbracoAlias);
                    if (ctrl != null)
                        ctrl.RefreshLabel(content.getProperty(config.Aliases.FileSizeAlias.UmbracoAlias).Value.ToString());
                }
                    // ReSharper disable EmptyGeneralCatchClause
                catch
                    // ReSharper restore EmptyGeneralCatchClause
                {
                }
            }
        }

        public bool TreatAsRichTextEditor {
            get { return false; }
        }

        public bool ShowLabel {
            get { return true; }
        }

        #endregion

        private static T FindControlRecursive<T>(Control parent, string id) where T : Control {
            if ((parent is T) && (parent.ID == id)) return (T)parent;

            foreach (Control control in parent.Controls) {
                var foundControl = FindControlRecursive<T>(control, id);
                if (foundControl != null) return foundControl;
            }
            return default(T);
        }

        protected override void Render(HtmlTextWriter output) {
            try {
                var cfg = Business.Configuration.ProtectedMedia.Instance;
                var content = Content.GetContentFromVersion(_defaultData.Version);

                if (content.getProperty(cfg.Aliases.FileAlias.UmbracoAlias).Value != null
                    && !string.IsNullOrEmpty(content.getProperty(cfg.Aliases.FileAlias.UmbracoAlias).Value.ToString())) {
                    output.WriteLine(string.Format("<a href=\"{0}\" target=\"_blank\">{1}</a><br />",
                                                   content.getProperty(cfg.Aliases.FileAlias.UmbracoAlias).Value,
                                                   content.getProperty(cfg.Aliases.InternalFileAlias.UmbracoAlias).Value));
                    output.WriteLine(string.Format(
                                         "<input type=\"checkbox\" id=\"{0}{1}\" name=\"{0}{1}\" value=\"1\"/><label for=\"{0}{1}\">{2}</label><br />",
                                         ClientID, Constants.ClearFieldHtmlId, ui.Text("uploadClear")));
                    output.WriteLine(string.Format("<input type=\"hidden\" id=\"{0}{1}\" name=\"{0}{1}\" value=\"{2}\"/>",
                                                   ClientID, Constants.HiddenFieldHtmlId, _defaultData.NodeId));
                }

                base.Render(output);
            }
                // ReSharper disable EmptyGeneralCatchClause
            catch { }
            // ReSharper restore EmptyGeneralCatchClause
        }

        private static string GetExtension(string filename) {
            var position = filename.LastIndexOf(@".");
            var length = filename.Length;

            return filename.Substring(position + 1, (length - position) - 1).ToLower();
        }

        private static string Hash(int mediaNodeId) {
            return new Library().GenerateSHA1(mediaNodeId);
        }

        private static string InternalDownloadHash(int mediaNodeId) {
            return new Library().GenerateInternalDownloadSHA1(mediaNodeId);
        }
    }
}